package com.larry.tinyweb.core.annotation;

import com.larry.tinyweb.db.util.AppUtil;

import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by larry on 16/12/12.
 * @author larry
 *
 * 此类将classpath下类的注解装载到AnnotationContainer中
 */
public class AnnotationLoader {
    private Map<String, String> classPkgMap;
    private String classPath = "";
    private AnnotationContainer container;


    public AnnotationLoader(AnnotationContainer container) {
        this.classPkgMap = new HashMap();
        this.container = container;

        if (AppUtil.rootPath.indexOf("WEB-INF") > 0) {
            classPath = AppUtil.webClassPath = AppUtil.rootPath.substring(0, AppUtil.rootPath.lastIndexOf("WEB-INF")) +
                    "WEB-INF" + File.separator + "classes" + File.separator;
        }
    }

    /**
     * 扫M注解
     *
     * @throws MalformedURLException
     * @throws ClassNotFoundException
     */
    public void scannerAnnotation() {
        File cPath = new File(classPath);
        scannerClassToClassPkgMap(cPath);
        try {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            load(classLoader, classPkgMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化加载注解
     *
     * @param classLoader
     * @param map
     * @throws ClassNotFoundException
     */
    private void load(ClassLoader classLoader, Map<String, String> map) throws Exception {
        for (String className : map.keySet()) {
            String classPkg = map.get(className);
            container.put(classLoader.loadClass(classPkg));
        }
    }

    /**
     * 扫描classPath下的所有类
     * 将结果放在classPkgMap内，key是className，value是包全名加className
     *
     * @param path
     */
    private void scannerClassToClassPkgMap(File path) {
        if (path.isDirectory()) {
            for (File file : path.listFiles()) {
                if (file.isDirectory()) {
                    scannerClassToClassPkgMap(file);
                } else {
                    loadClassToClassPkgMap(file);
                }
            }
        } else {
            loadClassToClassPkgMap(path);
        }
    }

    /**
     * 加载单个class到classPkgMap内
     *
     * @param file
     */
    private void loadClassToClassPkgMap(File file) {
        if (file.isFile() && file.getName().endsWith("class")) {
            String className = file.getName().substring(0, file.getName().lastIndexOf(".class"));

            String pkgPath = file.getPath()
                    .substring(classPath.length(), file.getPath().length())
                    .replace(".class", "")
                    .replaceAll(File.separator, ".");

            classPkgMap.put(className, pkgPath);
        }
    }
}
